package utils

import (
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"
)

func EncryptPhoneNumber(phone string) string {
	if len(phone) != 11 {
		return phone
	}
	return phone[:3] + "******" + phone[9:]
}

func ParseInt(b string, defInt int) int {
	id, err := strconv.Atoi(b)
	if err != nil {
		return defInt
	} else {
		return id
	}
}

/**
 * int转换string
 */
func ParseString(b int) string {
	str := strconv.Itoa(b)
	return str
}

/**
 * int64转换string
 */
func ParseStringInt64(b int64) string {
	str := strconv.FormatInt(b, 10)
	return str
}

/**
 * string转int64
 */
func ParseInt64String(b string) int64 {
	id, _ := strconv.ParseInt(b, 10, 64)
	return id
}

/**
 * 转换浮点数为string
 */
func ParseFloat64ToString(f float64, prec int) string {
	return strconv.FormatFloat(f, 'f', prec, 64)
}

/**
 * 转换string为浮点数
 */
func ParseStringFloat64(s string) float64 {
	f, _ := strconv.ParseFloat(s, 64)
	return f
}

/*
 * 生成随机字符串
 */
func GetRandomString(n int, more ...bool) string {
	var letterBytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
	if len(more) > 0 && more[0] == true {
		letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()+[]{}/<>;:=.,?"
	}
	rand.Seed(time.Now().UnixNano())
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))]
	}
	return string(b)
}

/*
 * 生成随机数字
 */
func GetRandomInt(n int) string {
	numeric := [10]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	r := len(numeric)
	rand.Seed(time.Now().UnixNano())

	var sb strings.Builder
	for i := 0; i < n; i++ {
		fmt.Fprintf(&sb, "%d", numeric[rand.Intn(r)])
	}
	return sb.String()
}

/*
 * Md5加密
 */
func Md5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

/*
 * Sha1加密
 */
func Sha1(data string) string {
	sha1 := sha1.New()
	sha1.Write([]byte(data))
	return hex.EncodeToString(sha1.Sum([]byte("")))
}

/*
 * Sha256加密
 */
func Sha256(data string) []byte {
	h := sha256.New()
	h.Write([]byte(data))
	return h.Sum(nil)
}

//数组相关函数

/*
 * 字符串是否在数组中
 */
func InArray(need string, needArr []string) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

/*
 * int是否在数组中
 */
func InArrayInt(need int, needArr []int) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

/*
 * int64是否在数组中
 */
func InArrayInt64(need int64, needArr []int64) bool {
	for _, v := range needArr {
		if need == v {
			return true
		}
	}
	return false
}

/**
 * 数组去重 去空
 */
func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
	a_len := len(a)
	for i := 0; i < a_len; i++ {
		if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
			continue
		}
		ret = append(ret, a[i])
	}
	return
}

//时间相关函数

/**
 * 获取当前时间戳
 */
func Time() int64 {
	return time.Now().Unix()
}

//Date(1524799394,"02/01/2006 15:04:05 PM")

/**
 * 通过时间戳获取格式
 * Date(1524799394,"02/01/2006 15:04:05 PM")
 */

/**
 * 字符串转时间戳
 */
// Strtotime strtotime()
// Strtotime("02/01/2016 15:04:05","02/01/2006 15:04:05") == 1451747045
// Strtotime("3 04 PM", "8 41 PM") == -62167144740
func Strtotime(strtime string, formatArg ...string) (int64, error) {
	var format = "2006-01-02 15:04:05"
	if len(formatArg) > 0 && formatArg[0] != "" {
		format = formatArg[0]
	}
	//t, err := time.Parse(format, strtime)
	t, err := time.ParseInLocation(format, strtime, time.Local)
	if err != nil {
		return 0, err
	}
	return t.Unix(), nil
}

/**
 * 通用输入类型比较
 */
func CheckType(str string, ct string) bool {
	if str == "" || ct == "" {
		return false
	}
	var pattern string
	switch strings.ToLower(ct) {
	case "email":
		pattern = `^[0-9a-zA-Z][_.0-9a-zA-Z-]{0,31}@([0-9a-zA-Z][0-9a-zA-Z-]{0,30}[0-9a-zA-Z]\.){1,4}[a-zA-Z]{2,4}$`
	case "phone":
		pattern = `^1\d{10}$`
	case "url":
		pattern = `^(http|https):\/\/.*$`
	case "number":
		pattern = `^\d+$`
	case "letter":
		pattern = `^[a-zA-Z]+$`
	default:
		return false
	}
	reg := regexp.MustCompile(pattern)
	return reg.MatchString(str)
}

/**
 * stacktrace信息裁剪
 */
func CutStack(stack string, startLine, endLine int) string {
	if endLine <= startLine {
		endLine = startLine + 4
	}
	stackArr := strings.Split(stack, "\n")
	vStr := ""
	i := 0
	for _, v := range stackArr {
		if i >= startLine && i <= endLine {
			vStr += v + "\n"
		}
		i++
	}
	return vStr
}
